﻿#pragma once
#include "Rect.h"

template<typename T>
class FArray2D : TArray<T>
{
public:
	
	FRect* bounds;

	T* defaultT;
	
public:
	
	FArray2D(int width, int height)
	{
		bounds = new FRect(0, 0, width, height);
		for (int i = 0; i < width * height; ++i)
		{
			auto t = T();
			this->Emplace(t);
			// if (typeof(T).IsAbstract)
			// {
			// 	Add(default(T));    //null类型，需要自己重新往里面放
			// }
			// else
			// {
			// 	var value = System.Activator.CreateInstance<T>();
			// 	Add(value);
			// }
		}
		defaultT = new T();
	}
	FArray2D(int width, int height, T value)
	{
		bounds = new FRect(0, 0, width, height);
		for (int i = 0; i < width * height; ++i)
		{
			this->Emplace(T());
		}
	}
	

	int width()
	{
		return bounds->width();
	}
	int height()
	{
		return bounds->height();
	}
	
	T& Get(FVec* pos)
	{
		int id = pos->y * width() + pos->x;
		if (id >= this->Count())
		{
			UE_LOG(LogTD, Error, TEXT("获取越界： %d %d"), id, this->Num());
			return &(*defaultT);
		}
		return (*this)[id];
	}
		
	T& Get(int x, int y)
	{
		int id = y * width() + x;
		if (id >= this->Count())
		{
			UE_LOG(LogTD, Error, TEXT("获取越界： %d %d"), id, this->Num());
			return &(*defaultT);
		}
		return (*this)[id];
	}
		
	T Get(int index)
	{
		return (*this)[index];
	}

	void Set(FVec* pos, T value)
	{
		(*this)[pos->y * width() + pos->x] = value;
	}
		
	void Set(int x, int y, T value)
	{
		(*this)[y * width() + x] = value;
	}
		
	int Count()
	{
		return this->Num();
	}
};
